﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using tcm.entity;
using tcm.request.System;
using GCC.Container.Abstracts;

namespace tcm.utils
{
    public static class AuthManager
    {

        /// <summary>
        /// 每次启动得AESkey不同,每次的token加密则发生改变
        /// 如果不想拥有这个保护机制,把key与VI设置成固定值即可,比如,这个值在GCCEntrance进行初始化 Key与VI是可以赋值的.
        /// </summary>
        private static readonly Aes _aes = Aes.Create();
        /// <summary>
        /// 所有的角色缓存
        /// </summary>
        internal static readonly List<SysRole> _roles = new();
        /// <summary>
        /// 所有的访问区域缓存
        /// </summary>
        internal static readonly List<string> _permissions = new();

        /// <summary>
        /// 根据Token获取用户信息
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="request">请求</param>
        /// <returns></returns>
        public static LoginUser? GetUserInfoByToken(AbsGCCContext context, string token)
        {
            var currentUIDStr = DecryptStringFromBytes_Aes(token);//这句是用来防止用户使用上次的token(系统重启前)来欺骗系统,例如一个长期运行的token要想关闭此功能,注释这句话的同时将_aes得key与IV固定
            #if DEBUG
            if (token == "testUserToken")
            {
                currentUIDStr = "123";
            }
            #endif

            if (string.IsNullOrWhiteSpace(currentUIDStr) || !long.TryParse(currentUIDStr, out var _))
            {
                return null;
            }
            var userInfo = context.TryGet<LoginUser>(token).Result;
            if (userInfo is null)
            {
                return null;
            }

            return userInfo;
        }

        /// <summary>
        /// 加密一个字符串
        /// </summary>
        /// <param name="plainText">原始文字</param>
        /// <returns>加密结果</returns>
        public  static string? EncryptStringToBytes_Aes(string plainText)
        {
            if (string.IsNullOrWhiteSpace(plainText))
            {
                return null;
            }
            try
            {
                byte[] encrypted;
                using Aes aesAlg = Aes.Create();

                aesAlg.Key = _aes.Key;
                aesAlg.IV = _aes.IV;

                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
                using MemoryStream msEncrypt = new();
                using CryptoStream csEncrypt = new(msEncrypt, encryptor, CryptoStreamMode.Write);
                using StreamWriter swEncrypt = new(csEncrypt);
                swEncrypt.Write(plainText);
                swEncrypt.Flush();
                swEncrypt.Close();
                encrypted = msEncrypt.ToArray();



                return BitConverter.ToString(encrypted).Replace("-", "");
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 解密一个字符串
        /// </summary>
        /// <param name="cipherText">原始文字</param>
        /// <returns>解密结果</returns>
        private static string? DecryptStringFromBytes_Aes(string cipherText)
        {
            if (string.IsNullOrWhiteSpace(cipherText))
            {
                return null;
            }
            try
            {
                byte[] buf1 = new byte[cipherText.Length / 2];
                for (int i = 0; i < cipherText.Length; i += 2)
                {
                    buf1[i / 2] = Convert.ToByte(cipherText[i..(i + 2)], 16);
                }
                using Aes aesAlg = Aes.Create();
                aesAlg.Key = _aes.Key;
                aesAlg.IV = _aes.IV;
                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
                using MemoryStream msDecrypt = new(buf1);
                using CryptoStream csDecrypt = new(msDecrypt, decryptor, CryptoStreamMode.Read);
                using StreamReader srDecrypt = new(csDecrypt);
                return srDecrypt.ReadToEnd();
            }
            catch
            {
                return null;
            }
        }

    }
}
